package sing.rabbit.consumer.usage;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Profile;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.util.Map;

import static sing.rabbit.common.configurations.SimpleConfiguration.SIMPLE_QUEUE_NAME;


/**
 * 使用 @RabbitListener 示例2 <br>
 * --- <br>
 * 相较于 @RabbitListener 示例 1，本例使用更简单好用，没那么多问题，（也根本没用到 @RabbitHandler ，更别说设置什么 isDefault = true）<br>
 * 无论 Provider 发送的是 Message 还是 String，如果只接收消息体都可以使用 String 或 byte[] 作为参数，而不必区分。且可只接收 @Header 或 @Headers 注解的参数 <br>
 * --- <br>
 * 官方文档 @RabbitListener 可接受的参数类型见：https://docs.spring.io/spring-amqp/docs/current/reference/html/#async-annotation-driven-enable-signature
 *
 * @author xing
 * @date 2022/9/7 18:19
 */
@Profile("sample_2")
@Component
public class SimpleQueueListener2 {

    /**
     * 如果与下边的一起都监听，<br>
     * 二者会争抢接收消息，在一开始 Provider 累积未接收的消息被一开始争抢到方法的处理后（猜测，实际可能还会每条都争，但例子没看出来），可能会出现依次接收到消息的现象
     *
     * @param message
     */
    @RabbitListener(queues = SIMPLE_QUEUE_NAME)
    public void receive(Message message) {
        System.out.println("in 1");
        System.out.println(" [x] Received '" + new String(message.getBody()) + "'");
    }

    /**
     * @Payload 通过 注解获取 Message 中 body (message.getBody())<br>
     * @Headers 通过 注解获取 Message 中 headers (message.getMessageProperties().getHeaders()) <br>
     *          通过打印 Headers 可以发现很多由 Rabbit 往 Headers 添加的属性 和（及） 值
     * @Header 通过 注解获取 Headers 中单个属性: <br>
     *         public void receive(@Header String token) <br>
     *         public void receive(@Header("token") String theToken) <br>
     *
     */
    @RabbitListener(queues = SIMPLE_QUEUE_NAME)
    public void receive(@Payload String body, @Headers Map<String, Object> headers) {
        System.out.println("in 2");
        System.out.println(" [x] Received '" + body + "'");
        // System.out.println("received headers: " + headers);
    }

    /**
     * 可以单独使用加了 @Headers 注解的参数，而不接收消息体 。也可以值接收 Body 不接收其他参数。<br>
     * 消息体上 @Payload 可以不加 <br>
     * 如 <br>
     * public void receive(String body, @Headers Map<String, Object> headers) <br>
     * public void receive(@Headers Map<String, Object> headers, String body) <br>
     * public void receive(String body) <br>
     * 无论 Provider 发送的消息类型是 String 还是 Message ，<strong>都可以</strong> 使用 String body 作为参数，并正常接收到消息体。、<br>
     * 不过参数也可以是 byte[] body: <br>
     * public void receive(String body) <br>
     * 由于 Message 的 toString 是不会变的，所以如果参数为 Message，发送的是 Message 类型消息，直接打印，其 body 仍显示为 [Bxxx
     */
    public void forIdeaView() {
        // 为了让 IDEA 能转换注释形式，没其他用处
    }

}
